4 在bean factory中创造 bean
写在前面:该 part 是 Spring ioc 的核心,显得非常冗杂,Spring 内不知名的组件非常的多,有很多笔者也难以描述清楚,甚至也没见过。在介绍的时候会做适当的忽略。
该 part 的起点:
public AnnotationConfigApplicationContext(Class<?>... annotatedClasses) {
this();
register(annotatedClasses);
refresh(); // 4 在 bean factory 中创造 bean
}
来追踪这个方法的实现:
//AbstractApplicationContext.class
public void refresh() throws BeansException, IllegalStateException {
synchronized (this.startupShutdownMonitor) {
//准备工作的配置
//4.3
prepareRefresh();
//获取 bean factory
//4.4
ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();
//配置 bean factory
//4.5
prepareBeanFactory(beanFactory);
try {
//4.6
postProcessBeanFactory(beanFactory);
//4.7
invokeBeanFactoryPostProcessors(beanFactory);
//4.8
registerBeanPostProcessors(beanFactory);
//4.9
initMessageSource();
//4.10
initApplicationEventMulticaster();
//4.11
onRefresh();
//4.12
registerListeners();
//4.13
finishBeanFactoryInitialization(beanFactory);
//4.15
finishRefresh();
}catch (BeansException ex) {
if (logger.isWarnEnabled()) {
logger.warn("Exception encountered during context initialization - " +
"cancelling refresh attempt: " + ex);
}
//4.16
destroyBeans();
//4.17
cancelRefresh(ex);
throw ex;
}finally {
//4.18
resetCommonCaches();
}
}
}
4.1
在开始之前先来看一下 BeanPostProcessor:
public interface BeanPostProcessor {
//此方法在 bean 初始化之前、bean 的构造方法调用之后执行
@Nullable
default Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
return bean;
}
//此方法在 bean 初始化之后执行
@Nullable
default Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
return bean;
}
}
BeanPostProcessor 在 bean 的注册阶段就已经大量接触到了,在下列 bean 的创建阶段会更多的遇到,是 Spring ioc 的重要组成部分。
Spring 容器本身在初始化的时候就会注册很多个 BeanPostProcessor 接口的实现类到 BeanFactory 中。这些类会被 BeanFactory 实例成 bean,并特殊存放到一个列表中。在其它普通 bean 的初始化(即为 init 方法被调用时)之前,轮循 BeanPostProcessor 列表,执行 postProcessBeforeInitialization(...) 方法;在其它普通 bean 的初始化之后,再次轮训 BeanPostProcessor 列表,执行 postProcessAfterInitialization(...) 方法。
从出入参可知,这两个方法用于在 bean 的初始化阶段对 bean 进行功能增强操作,包括但不限于代码织入(asm)、切面操作(aop)等。
作为 Spring 的使用者,只要是自行编写实现了该接口的类,然后通过配置将该类作为 Bean 注册到 Spring 中,就会被 Spring 一视同仁的作为内部 BeanPostProcessor 对待。
4.2
再来看一下创建 bean 的核心方法,即 BeanUtil.instantiateClass(...):
//BeanUtil.class
public static <T> T instantiateClass(Constructor<T> ctor, Object... args) throws BeanInstantiationException {
Assert.notNull(ctor, "Constructor must not be null");
try {
//设置 accessible = true,即为去掉 privite 关键词对构造的影响
ReflectionUtils.makeAccessible(ctor);
//这个返回语句主要是为了兼容 kotlin 语言,对于 java 来说主要是 ctor.newInstance(args)
//本质是调用 bean 的构造器来实例化 bean
return (KotlinDetector.isKotlinReflectPresent() && KotlinDetector.isKotlinType(ctor.getDeclaringClass()) ?
KotlinDelegate.instantiateClass(ctor, args) : ctor.newInstance(args));
}catch (InstantiationException ex) {
throw new BeanInstantiationException(ctor, "Is it an abstract class?", ex);
}catch (IllegalAccessException ex) {
throw new BeanInstantiationException(ctor, "Is the constructor accessible?", ex);
}catch (IllegalArgumentException ex) {
throw new BeanInstantiationException(ctor, "Illegal arguments for constructor", ex);
}catch (InvocationTargetException ex) {
throw new BeanInstantiationException(ctor, "Constructor threw exception", ex.getTargetException());
}
}
BeanUtil 是 bean 的实例化的关键,Spring 的其它代码都是在做各种判断,但是真正实例化 bean 的就这一句。
4.3
看下方代码片段:
//AbstractApplicationContext.class
protected void prepareRefresh() {
//记录下启动时间
this.startupDate = System.currentTimeMillis();
//这两个变量与优雅关闭有关,这里确定 Spring 未关闭
this.closed.set(false);
this.active.set(true);
//logger 日志相关代码均不作描述了
if (logger.isDebugEnabled()) {
if (logger.isTraceEnabled()) {
logger.trace("Refreshing " + this);
}
else {
logger.debug("Refreshing " + getDisplayName());
}
}
//初始化 property
//该方法是空的
initPropertySources();
//检查读取到的 properties 键值对
getEnvironment().validateRequiredProperties();
//新建一个集合,这个集合用于储存需要立即通知的事件
this.earlyApplicationEvents = new LinkedHashSet<>();
}
closed 和 active 都是定义在 AbstractApplicationContext 中的 AtomicBoolean,用以管理 Spring 容器的状态:
//容器是否处于活动中
private final AtomicBoolean active = new AtomicBoolean();
//容器是否已经关闭
private final AtomicBoolean closed = new AtomicBoolean();
initPropertySources() 方法其实是一个预留下的空方法:
//AbstractApplicationContext.class
protected void initPropertySources() {
}
getEnvironment() 在之前的代码里看到过,用来获取一个新创建出来的 StandardEnvironment 对象,而 validateRequiredProperties() 是定义在 AbstractEnvironment 中的方法:
//AbstractEnvironment.class
public void validateRequiredProperties() throws MissingRequiredPropertiesException {
this.propertyResolver.validateRequiredProperties();
}
propertyResolver 是一个定义在 AbstractEnvironment 中的 PropertySourcesPropertyResolver 对象,顾名思义,是用来管理 properties 配置文件中读取到的值的。来看一下 validateRequiredProperties():
//AbstractPropertyResolver.class
public void validateRequiredProperties() {
//新建了一个 Exception,用于在出错情况下进行返回
MissingRequiredPropertiesException ex = new MissingRequiredPropertiesException();
//这里的字面意思上可以看出,这个 for 循环语句用于从 requiredProperties 这个集合里获取每个 properties key
for (String key : this.requiredProperties) {
//getProperty(key) 方法会用 key 去获取 value 值,然后进行空值比对
if (this.getProperty(key) == null) {
//如果存在 null,则加入到错误信息里
ex.addMissingRequiredProperty(key);
}
}
//错误信息不为空,证明上述代码中存在值为 null 的,就直接抛出异常
if (!ex.getMissingRequiredProperties().isEmpty()) {
throw ex;
}
}
4.4
看下方代码片段:
ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();
追踪 obtainFreshBeanFactory() 方法:
//AbstractApplicationContext.class
protected ConfigurableListableBeanFactory obtainFreshBeanFactory() {
refreshBeanFactory();
return getBeanFactory();
}
追踪 refreshBeanFactory() 方法的内部实现:
//GenericApplicationContext.class
protected final void refreshBeanFactory() throws IllegalStateException {
if (!this.refreshed.compareAndSet(false, true)) {
//抛出错误,提示大意为:已经调用过一次 "refresh" 了
throw new IllegalStateException(
"GenericApplicationContext does not support multiple refresh attempts: just call 'refresh' once");
}
//存入一个用于序列化的 id
this.beanFactory.setSerializationId(getId());
}
refreshed 是一个定义在 GenericApplicationContext 中的 AtomicBoolean 类型对象。AtomicBoolean 的 compareAndSet(...) 方法等同于进行如下操作:
//比较 AtomicBoolean 当前的值和第一个参数是否相等,如果一致,则将 AtomicBoolean 当前的值换成第二个值。
//以下为模拟代码,AtomicBoolean 的真实实现大多数是使用虚拟机底层代码完成,是原子化的操作
if(atomicBoolean == false){
atomicBoolean = true;
return true;
}else{
return false;
}
this.beanFactory.setSerializationId(getId()) 会将 AbstractApplicationContext 内的 id 存入一个定义在 DefaultListableBeanFactory 中的 map 对象里。
4.5
看下方代码片段:
prepareBeanFactory(beanFactory);
追踪代码实现:
//AbstractApplicationContext.class
protected void prepareBeanFactory(ConfigurableListableBeanFactory beanFactory) {
//存入 AnnotationConfigApplicationContext 中的 classLoader
beanFactory.setBeanClassLoader(getClassLoader());
//StandardBeanExpressionResolver 用于解析 Spring EL 表达式的解析器
beanFactory.setBeanExpressionResolver(new StandardBeanExpressionResolver(beanFactory.getBeanClassLoader()));
//ResourceEditorRegistrar 用于各种 bean 与 String 之间进行转换的属性编辑器
beanFactory.addPropertyEditorRegistrar(new ResourceEditorRegistrar(this, getEnvironment()));
//ApplicationContextAwareProcessor 用于注入各类 aware bean
beanFactory.addBeanPostProcessor(new ApplicationContextAwareProcessor(this));
//在自动装配(autowire)阶段要忽略的接口类
beanFactory.ignoreDependencyInterface(EnvironmentAware.class);
beanFactory.ignoreDependencyInterface(EmbeddedValueResolverAware.class);
beanFactory.ignoreDependencyInterface(ResourceLoaderAware.class);
beanFactory.ignoreDependencyInterface(ApplicationEventPublisherAware.class);
beanFactory.ignoreDependencyInterface(MessageSourceAware.class);
beanFactory.ignoreDependencyInterface(ApplicationContextAware.class);
//自动装配的规则
beanFactory.registerResolvableDependency(BeanFactory.class, beanFactory);
beanFactory.registerResolvableDependency(ResourceLoader.class, this);
beanFactory.registerResolvableDependency(ApplicationEventPublisher.class, this);
beanFactory.registerResolvableDependency(ApplicationContext.class, this);
//ApplicationListenerDetector 用于类型是 ApplicationListener 的bean添加到事件广播器
beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(this));
//代码动态织入
//LOAD_TIME_WEAVER_BEAN_NAME = "loadTimeWeaver"
if (beanFactory.containsBean(LOAD_TIME_WEAVER_BEAN_NAME)) {
//LoadTimeWeaverAwareProcessor 用于在 bean 初始化之前检查 bean 是否实现了LoadTimeWeaverAware 接口
//与 Spring aop 代码织入相关的 BeanPostProcessor
beanFactory.addBeanPostProcessor(new LoadTimeWeaverAwareProcessor(beanFactory));
//用于类型匹配的 classloader
beanFactory.setTempClassLoader(new ContextTypeMatchClassLoader(beanFactory.getBeanClassLoader()));
}
//注册 properties 和 environment 相关的 bean
//这里不仅会注册,而且会直接将这些 bean 存放到 singleObject 中(即为直接实例化出来)
if (!beanFactory.containsLocalBean(ENVIRONMENT_BEAN_NAME)) {
beanFactory.registerSingleton(ENVIRONMENT_BEAN_NAME, getEnvironment());
}
if (!beanFactory.containsLocalBean(SYSTEM_PROPERTIES_BEAN_NAME)) {
beanFactory.registerSingleton(SYSTEM_PROPERTIES_BEAN_NAME, getEnvironment().getSystemProperties());
}
if (!beanFactory.containsLocalBean(SYSTEM_ENVIRONMENT_BEAN_NAME)) {
beanFactory.registerSingleton(SYSTEM_ENVIRONMENT_BEAN_NAME, getEnvironment().getSystemEnvironment());
}
}
代码动态织入是 Spring 底层 cglib 的相关概念,暂时不展开。
4.6
看下方代码片段:
postProcessBeanFactory(beanFactory);
在 AbstractApplicationContext 中该方法是一个空方法:
//AbstractApplicationContext.class
protected void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) {
}
该方法预留给 AbstractApplicationContext 的子类去实现,目的是在 bean factory 装配完成之后做一些定制化处理 AbstractApplicationContext。在 AnnotationConfigApplicationContext 及其父类中没有重写该方法。
4.7
看下方代码片段:
invokeBeanFactoryPostProcessors(beanFactory);
追踪代码实现:
//AbstractApplicationContext.class
protected void invokeBeanFactoryPostProcessors(ConfigurableListableBeanFactory beanFactory) {
PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(beanFactory, getBeanFactoryPostProcessors());
if (beanFactory.getTempClassLoader() == null && beanFactory.containsBean(LOAD_TIME_WEAVER_BEAN_NAME)) {
beanFactory.addBeanPostProcessor(new LoadTimeWeaverAwareProcessor(beanFactory));
beanFactory.setTempClassLoader(new ContextTypeMatchClassLoader(beanFactory.getBeanClassLoader()));
}
}
这段代码和上述 4.4 中的一段几乎是一摸一样的,Spring 在这里做了二次验证。
4.8
看下方代码片段:
registerBeanPostProcessors(beanFactory);
从字面意思可以看出就是在 beanFactory 中注册 BeanPostProcessor。注册的本质是将 BeanPostProcessor 保存到一个列表里。从源码里看,该列表是定义在 AbstractBeanFactory 中的 beanPostProcessors。
追踪代码实现:
//AbstractApplicationContext.class
protected void registerBeanPostProcessors(ConfigurableListableBeanFactory beanFactory) {
PostProcessorRegistrationDelegate.registerBeanPostProcessors(beanFactory, this);
}
继续追踪:
//PostProcessorRegistrationDelegate.class
public static void registerBeanPostProcessors(
ConfigurableListableBeanFactory beanFactory, AbstractApplicationContext applicationContext) {
//根据 class 获取到所有符合的 bean,即 BeanPostProcessor 的子类
String[] postProcessorNames = beanFactory.getBeanNamesForType(BeanPostProcessor.class, true, false);
//beanFactory.getBeanPostProcessorCount() 获取到的数字是在 4.4 中 set 的 BeanPostProcessor 的数量
int beanProcessorTargetCount = beanFactory.getBeanPostProcessorCount() + 1 + postProcessorNames.length;
//BeanPostProcessorChecker 是 PostProcessorRegistrationDelegate 的私有静态内部类
//如果一个 bean 没有被所有的 BeanPostProcessor 处理完毕,BeanPostProcessorChecker 就会打印日志
beanFactory.addBeanPostProcessor(new BeanPostProcessorChecker(beanFactory, beanProcessorTargetCount));
//处理 Order 相关接口
//Order 是一个用于排序的接口
//用于存放实现了 PriorityOrdered 接口的 BeanPostProcessor
List<BeanPostProcessor> priorityOrderedPostProcessors = new ArrayList<>();
//用于存放实现了 MergedBeanDefinitionPostProcessor 接口的 BeanPostProcessor
List<BeanPostProcessor> internalPostProcessors = new ArrayList<>();
//用于存放实现了 Ordered 接口的 BeanPostProcessor
List<String> orderedPostProcessorNames = new ArrayList<>();
//其它 BeanPostProcessor
List<String> nonOrderedPostProcessorNames = new ArrayList<>();
for (String ppName : postProcessorNames) {
//isTypeMatch(...) 方法会判断该名称的 bean 和 class 类型是否一致
//这里查看是否实现了 PriorityOrdered 接口
if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
//获取 bean 并添加到一个列表中
BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);
priorityOrderedPostProcessors.add(pp);
if (pp instanceof MergedBeanDefinitionPostProcessor) {
//继续判断是否实现了 MergedBeanDefinitionPostProcessor 接口
internalPostProcessors.add(pp);
}
}else if (beanFactory.isTypeMatch(ppName, Ordered.class)) {
//如果并非实现了 PriorityOrdered 接口就判断是否实现了 Ordered 接口
orderedPostProcessorNames.add(ppName);
}else {
//均无,则存入 nonOrderedPostProcessorNames 列表中
nonOrderedPostProcessorNames.add(ppName);
}
}
//对于实现了 PriorityOrdered 接口的 BeanPostProcessor 进行排序
sortPostProcessors(priorityOrderedPostProcessors, beanFactory);
//依次注册这些 BeanPostProcessor
registerBeanPostProcessors(beanFactory, priorityOrderedPostProcessors);
//下方代码块和上方很雷同,注册实现了 Ordered 接口的 BeanPostProcessor
List<BeanPostProcessor> orderedPostProcessors = new ArrayList<>();
for (String ppName : orderedPostProcessorNames) {
BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);
orderedPostProcessors.add(pp);
if (pp instanceof MergedBeanDefinitionPostProcessor) {
internalPostProcessors.add(pp);
}
}
sortPostProcessors(orderedPostProcessors, beanFactory);
registerBeanPostProcessors(beanFactory, orderedPostProcessors);
//注册没有实现任何排序接口的 BeanPostProcessor
List<BeanPostProcessor> nonOrderedPostProcessors = new ArrayList<>();
for (String ppName : nonOrderedPostProcessorNames) {
BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);
nonOrderedPostProcessors.add(pp);
if (pp instanceof MergedBeanDefinitionPostProcessor) {
internalPostProcessors.add(pp);
}
}
registerBeanPostProcessors(beanFactory, nonOrderedPostProcessors);
//对于实现了 MergedBeanDefinitionPostProcessor 接口的 BeanPostProcessor 会统一进行排序并注册
sortPostProcessors(internalPostProcessors, beanFactory);
registerBeanPostProcessors(beanFactory, internalPostProcessors);
//ApplicationListenerDetector 用于在 bean 初始化后检查是否实现了 ApplicationListener 接口
//从代码来看,实现了该接口的 bean 会被存入一个叫 applicationListeners 的列表中
beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(applicationContext));
}
综合来看这个方法的主体是对 BeanPostProcessor 进行依次的存储(会影响到 BeanPostProcessor 的执行顺序)。
次序的依据主要是看这些 BeanPostProcessor 是否实现了 Order 及其相关的接口。
4.9
看下方代码片段:
initMessageSource();
追踪代码实现:
//AbstractApplicationContext.class
protected void initMessageSource() {
//获取 beanFactory
ConfigurableListableBeanFactory beanFactory = getBeanFactory();
//MESSAGE_SOURCE_BEAN_NAME = "messageSource"
//先去查看 beanFactory 中是否有该名称的 bean
if (beanFactory.containsLocalBean(MESSAGE_SOURCE_BEAN_NAME)) {
//获取到这个 bean
this.messageSource = beanFactory.getBean(MESSAGE_SOURCE_BEAN_NAME, MessageSource.class);
//主体思路是将数据源存入这个 bean 中
if (this.parent != null && this.messageSource instanceof HierarchicalMessageSource) {
HierarchicalMessageSource hms = (HierarchicalMessageSource) this.messageSource;
if (hms.getParentMessageSource() == null) {
//存入默认的数据源
//getInternalParentMessageSource() 方法会先
hms.setParentMessageSource(getInternalParentMessageSource());
}
}
if (logger.isTraceEnabled()) {
logger.trace("Using MessageSource [" + this.messageSource + "]");
}
}else {
//没有这个 bean 的情况下就自定义一个,并存入到 beanFactory 中
DelegatingMessageSource dms = new DelegatingMessageSource();
dms.setParentMessageSource(getInternalParentMessageSource());
this.messageSource = dms;
beanFactory.registerSingleton(MESSAGE_SOURCE_BEAN_NAME, this.messageSource);
if (logger.isTraceEnabled()) {
logger.trace("No '" + MESSAGE_SOURCE_BEAN_NAME + "' bean, using [" + this.messageSource + "]");
}
}
}
Spring 中可以配置多套配置文件,之间通过 messageSource 进行切换。
4.10
看下方代码片段:
initApplicationEventMulticaster();
追踪代码实现:
//AbstractApplicationContext.class
protected void initApplicationEventMulticaster() {
ConfigurableListableBeanFactory beanFactory = getBeanFactory();
//APPLICATION_EVENT_MULTICASTER_BEAN_NAME = "applicationEventMulticaster"
//检查是否存在名称为 applicationEventMulticaster 的 bean
if (beanFactory.containsLocalBean(APPLICATION_EVENT_MULTICASTER_BEAN_NAME)) {
//如果存在则赋值给 applicationEventMulticaster
this.applicationEventMulticaster =
beanFactory.getBean(APPLICATION_EVENT_MULTICASTER_BEAN_NAME, ApplicationEventMulticaster.class);
if (logger.isTraceEnabled()) {
logger.trace("Using ApplicationEventMulticaster [" + this.applicationEventMulticaster + "]");
}
}else {
//没有的话就创建一个,并注册与赋值
this.applicationEventMulticaster = new SimpleApplicationEventMulticaster(beanFactory);
beanFactory.registerSingleton(APPLICATION_EVENT_MULTICASTER_BEAN_NAME, this.applicationEventMulticaster);
if (logger.isTraceEnabled()) {
logger.trace("No '" + APPLICATION_EVENT_MULTICASTER_BEAN_NAME + "' bean, using " +
"[" + this.applicationEventMulticaster.getClass().getSimpleName() + "]");
}
}
}
applicationEventMulticaster 是一个观察者模式的应用,可以理解为是用来分发数据给监听器(Listener)的中转站。
4.11
看下方代码片段:
onRefresh();
默认该方法为空:
//AbstractApplicationContext.class
protected void onRefresh() throws BeansException {
}
预留用于处理特殊的 bean。
4.12
registerListeners();
追踪代码实现:
//AbstractApplicationContext.class
protected void registerListeners() {
//遍历 applicationListeners 列表
//往 applicationEventMulticaster 内部的列表 applicationListeners 里添加
//applicationListener 用于在容器初始化时期监听事件
for (ApplicationListener<?> listener : getApplicationListeners()) {
getApplicationEventMulticaster().addApplicationListener(listener);
}
//获取可能存在的使用者自行定义的监听器,同样添加到列表里
String[] listenerBeanNames = getBeanNamesForType(ApplicationListener.class, true, false);
for (String listenerBeanName : listenerBeanNames) {
getApplicationEventMulticaster().addApplicationListenerBean(listenerBeanName);
}
//获取所有的 event,放到一个列表里
Set<ApplicationEvent> earlyEventsToProcess = this.earlyApplicationEvents;
this.earlyApplicationEvents = null;
if (earlyEventsToProcess != null) {
for (ApplicationEvent earlyEvent : earlyEventsToProcess) {
getApplicationEventMulticaster().multicastEvent(earlyEvent);
}
}
}
特定的监听器用于监听某一类的 event,在容器启动时生效,对 event 做出处理。
监听器被储存在 applicationEventMulticaster 中,发生事件的时候被告知。
4.13
finishBeanFactoryInitialization(beanFactory);
追踪代码实现:
//AbstractApplicationContext.class
protected void finishBeanFactoryInitialization(ConfigurableListableBeanFactory beanFactory) {
//CONVERSION_SERVICE_BEAN_NAME = "conversionService"
//conversionService 这个 bean 用于映射数据类型,比如将前端的字符串类型数据转成日期等
//由使用者自主实现并配置,默认情况下没有这个 bean
if (beanFactory.containsBean(CONVERSION_SERVICE_BEAN_NAME) &&
beanFactory.isTypeMatch(CONVERSION_SERVICE_BEAN_NAME, ConversionService.class)) {
beanFactory.setConversionService(
beanFactory.getBean(CONVERSION_SERVICE_BEAN_NAME, ConversionService.class));
}
//如果 beanFactory 里没有 embeddedValueResolver,就会从 environment 里获取并加载到里面
//embeddedValueResolver 是和配置文件读取相关的组件
if (!beanFactory.hasEmbeddedValueResolver()) {
beanFactory.addEmbeddedValueResolver((strVal) -> {
return this.getEnvironment().resolvePlaceholders(strVal);
});
}
//以下代码用于提前实例化代码织入相关的 bean
String[] weaverAwareNames = beanFactory.getBeanNamesForType(LoadTimeWeaverAware.class, false, false);
String[] var3 = weaverAwareNames;
int var4 = weaverAwareNames.length;
for(int var5 = 0; var5 < var4; ++var5) {
String weaverAwareName = var3[var5];
this.getBean(weaverAwareName);
}
//将 classLoader 置空,因为已经用不到了,所以清除掉,节省内存
beanFactory.setTempClassLoader((ClassLoader)null);
//这个方法会将 beanName 列表转换成一个字符串数组,节省内存
beanFactory.freezeConfiguration();
//实例化 bean 的核心方法
beanFactory.preInstantiateSingletons();
}
来看一下 beanFactory.preInstantiateSingletons() 方法:
//DefaultListableBeanFactory.class
public void preInstantiateSingletons() throws BeansException {
if (logger.isTraceEnabled()) {
logger.trace("Pre-instantiating singletons in " + this);
}
//将 beanName 列表拷贝一份
List<String> beanNames = new ArrayList<>(this.beanDefinitionNames);
//遍历
for (String beanName : beanNames) {
//获取每个 bean
RootBeanDefinition bd = getMergedLocalBeanDefinition(beanName);
//需要最终确认 bean 不是抽象类,且为单例的,且不是惰性加载的
if (!bd.isAbstract() && bd.isSingleton() && !bd.isLazyInit()) {
//判断其是否实现了 FactoryBean 接口
//FactoryBean 是 Spring 留出的可供使用者选择的用于生产 bean 的工厂模式接口
if (isFactoryBean(beanName)) {
Object bean = getBean(FACTORY_BEAN_PREFIX + beanName);
//二次判断
if (bean instanceof FactoryBean) {
final FactoryBean<?> factory = (FactoryBean<?>) bean;
//是否期望被 init
boolean isEagerInit;
//系统存在权限问题的时候才会进入到这个判断语句中
if (System.getSecurityManager() != null && factory instanceof SmartFactoryBean) {
//AccessController.doPrivileged(...) 方法用于 java 的权限控制
//此处调用了此方法用于剔除权限对 Spring 的控制
//此处与下方代码都调用了 SmartFactoryBean 接口的 isEagerInit() 方法进行判断
isEagerInit = AccessController.doPrivileged((PrivilegedAction<Boolean>)
((SmartFactoryBean<?>) factory)::isEagerInit,
getAccessControlContext());
}else {
isEagerInit = (factory instanceof SmartFactoryBean &&
((SmartFactoryBean<?>) factory).isEagerInit());
}
//实例化
if (isEagerInit) {
getBean(beanName);
}
}
}else {
//其实对于绝大多数普通的 bean,是直接调用这个语句进行实例化的
getBean(beanName);
}
}
}
//此处再次循环获取 bean ,用于对实现了 SmartInitializingSingleton 接口的 bean 进行特殊操作
//SmartInitializingSingleton 接口内有一个 afterSingletonsInstantiated() 方法,会在完成 bean 的实例化之后执行
for (String beanName : beanNames) {
Object singletonInstance = getSingleton(beanName);
if (singletonInstance instanceof SmartInitializingSingleton) {
final SmartInitializingSingleton smartSingleton = (SmartInitializingSingleton) singletonInstance;
if (System.getSecurityManager() != null) {
AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
smartSingleton.afterSingletonsInstantiated();
return null;
}, getAccessControlContext());
}else {
smartSingleton.afterSingletonsInstantiated();
}
}
}
}
4.14
所以最终实例化 bean 的是 getBean(...) 方法,此方法不仅可以用于从容器中取出 bean,也是实例化 bean 的具体实现。
追踪其具体代码实现:
//AbstractBeanFactory.class
public Object getBean(String name) throws BeansException {
return doGetBean(name, null, null, false);
}
继续来看 doGetBean(...) 方法:
//AbstractBeanFactory.class
protected <T> T doGetBean(final String name, @Nullable final Class<T> requiredType,
@Nullable final Object[] args, boolean typeCheckOnly) throws BeansException {
final String beanName = transformedBeanName(name);
Object bean;
//对于之前已经实例过的 bean,会在这个方法里获取到
//如果没有实例化过,那么此处获取的是 null
Object sharedInstance = getSingleton(beanName);
//args 是用于实例化 bean 过程中传入构造器的参数
//此处传入的 args 为 null
if (sharedInstance != null && args == null) {
if (logger.isTraceEnabled()) {
if (isSingletonCurrentlyInCreation(beanName)) {
logger.trace("Returning eagerly cached instance of singleton bean '" + beanName +
"' that is not fully initialized yet - a consequence of a circular reference");
}else {
logger.trace("Returning cached instance of singleton bean '" + beanName + "'");
}
}
//此方法用于处理 FactoryBean 的情况,如果没有的话是直接返回 sharedInstance 的
bean = getObjectForBeanInstance(sharedInstance, name, beanName, null);
}else {
//如果 bean 正在创建,会抛出异常
if (isPrototypeCurrentlyInCreation(beanName)) {
throw new BeanCurrentlyInCreationException(beanName);
}
//先取出父类中存放的 parentBeanFactory,如果有实现的话就用该工厂来创建 bean
//本例中没有使用 parentBeanFactory
BeanFactory parentBeanFactory = getParentBeanFactory();
if (parentBeanFactory != null && !containsBeanDefinition(beanName)) {
String nameToLookup = originalBeanName(name);
if (parentBeanFactory instanceof AbstractBeanFactory) {
return ((AbstractBeanFactory) parentBeanFactory).doGetBean(
nameToLookup, requiredType, args, typeCheckOnly);
}else if (args != null) {
return (T) parentBeanFactory.getBean(nameToLookup, args);
}else if (requiredType != null) {
return parentBeanFactory.getBean(nameToLookup, requiredType);
}else {
return (T) parentBeanFactory.getBean(nameToLookup);
}
}
//这里会将 bean 标记为已经创建
if (!typeCheckOnly) {
markBeanAsCreated(beanName);
}
try {
//获取 bean 的包装类
final RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);
//bean 不能是一个 abstract 修饰的类,否则会报错
checkMergedBeanDefinition(mbd, beanName, args);
//depends-on 用来处理要实例化某个 bean,必须先实例化另一个 bean 的情况
String[] dependsOn = mbd.getDependsOn();
if (dependsOn != null) {
for (String dep : dependsOn) {
//处理循环依赖的问题
if (isDependent(beanName, dep)) {
throw new BeanCreationException(mbd.getResourceDescription(), beanName,
"Circular depends-on relationship between '" + beanName + "' and '" + dep + "'");
}
//注册要依赖的 bean
registerDependentBean(dep, beanName);
try {
//实例化要依赖的 bean
getBean(dep);
}catch (NoSuchBeanDefinitionException ex) {
throw new BeanCreationException(mbd.getResourceDescription(), beanName,
"'" + beanName + "' depends on missing bean '" + dep + "'", ex);
}
}
}
//是否是单例的
if (mbd.isSingleton()) {
sharedInstance = getSingleton(beanName, () -> {
try {
//实例化 bean 的核心方法
return createBean(beanName, mbd, args);
}catch (BeansException ex) {
//如果报错的话会销毁掉这个 bean
destroySingleton(beanName);
throw ex;
}
});
bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
}else if (mbd.isPrototype()) {
//如果 scope 注解为 prototype,则每次获取 bean 的时候都会创建新的 bean 实例
Object prototypeInstance = null;
try {
beforePrototypeCreation(beanName);
prototypeInstance = createBean(beanName, mbd, args);
}
finally {
afterPrototypeCreation(beanName);
}
bean = getObjectForBeanInstance(prototypeInstance, name, beanName, mbd);
}else {
//获取 scope 注解的值,如果是 null 的话会报错
String scopeName = mbd.getScope();
final Scope scope = this.scopes.get(scopeName);
if (scope == null) {
throw new IllegalStateException("No Scope registered for scope name '" + scopeName + "'");
}
try {
//这一步的操作和上方代码块几乎是一样的
Object scopedInstance = scope.get(beanName, () -> {
beforePrototypeCreation(beanName);
try {
return createBean(beanName, mbd, args);
}finally {
afterPrototypeCreation(beanName);
}
});
bean = getObjectForBeanInstance(scopedInstance, name, beanName, mbd);
}catch (IllegalStateException ex) {
throw new BeanCreationException(beanName,
"Scope '" + scopeName + "' is not active for the current thread; consider " +
"defining a scoped proxy for this bean if you intend to refer to it from a singleton",
ex);
}
}
}catch (BeansException ex) {
cleanupAfterBeanCreationFailure(beanName);
throw ex;
}
}
//requiredType 是使用者传入的 class 对象,使用者可以将 bean 转换成该类型并输出
if (requiredType != null && !requiredType.isInstance(bean)) {
try {
T convertedBean = getTypeConverter().convertIfNecessary(bean, requiredType);
if (convertedBean == null) {
throw new BeanNotOfRequiredTypeException(name, requiredType, bean.getClass());
}
return convertedBean;
}catch (TypeMismatchException ex) {
if (logger.isTraceEnabled()) {
logger.trace("Failed to convert bean '" + name + "' to required type '" +
ClassUtils.getQualifiedName(requiredType) + "'", ex);
}
throw new BeanNotOfRequiredTypeException(name, requiredType, bean.getClass());
}
}
//返回 bean
return (T) bean;
}
继续追踪 createBean(...) 方法:
//AbstractAutowireCapableBeanFactory.class
protected Object createBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)
throws BeanCreationException {
if (logger.isTraceEnabled()) {
logger.trace("Creating instance of bean '" + beanName + "'");
}
RootBeanDefinition mbdToUse = mbd;
//获取 bean 的 class,然后在再次确定了 bean 的 class 无误之后,克隆一份 bean 并存入 bean class
Class<?> resolvedClass = resolveBeanClass(mbd, beanName);
if (resolvedClass != null && !mbd.hasBeanClass() && mbd.getBeanClassName() != null) {
mbdToUse = new RootBeanDefinition(mbd);
mbdToUse.setBeanClass(resolvedClass);
}
//重写的方法解析
try {
mbdToUse.prepareMethodOverrides();
}catch (BeanDefinitionValidationException ex) {
throw new BeanDefinitionStoreException(mbdToUse.getResourceDescription(),
beanName, "Validation of method overrides failed", ex);
}
try {
//根据注释来看,这个方法是使用 BeanPostProcessor 去进行动态代理
//如果存在对应的 BeanPostProcessor,返回的是动态代理的类,而不是 bean 本身
Object bean = resolveBeforeInstantiation(beanName, mbdToUse);
if (bean != null) {
return bean;
}
}catch (Throwable ex) {
throw new BeanCreationException(mbdToUse.getResourceDescription(), beanName,
"BeanPostProcessor before instantiation of bean failed", ex);
}
try {
//实例化 bean 的核心方法
Object beanInstance = doCreateBean(beanName, mbdToUse, args);
if (logger.isTraceEnabled()) {
logger.trace("Finished creating instance of bean '" + beanName + "'");
}
return beanInstance;
}catch (BeanCreationException | ImplicitlyAppearedSingletonException ex) {
throw ex;
}catch (Throwable ex) {
throw new BeanCreationException(
mbdToUse.getResourceDescription(), beanName, "Unexpected exception during bean creation", ex);
}
}
继续追踪 doCreateBean(...) 方法:
//AbstractAutowireCapableBeanFactory.class
protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, final @Nullable Object[] args)
throws BeanCreationException {
//BeanWrapper 是 bean 的另一种包装
BeanWrapper instanceWrapper = null;
if (mbd.isSingleton()) {
//factoryBeanInstanceCache 是一个 map 对象,用于缓存 wrapper
//此处从缓存中删除并返回此 wrapper
instanceWrapper = this.factoryBeanInstanceCache.remove(beanName);
}
//如果没有的话会创建一个
if (instanceWrapper == null) {
//这一步会实例化 bean
instanceWrapper = createBeanInstance(beanName, mbd, args);
}
//获取 bean 实例
final Object bean = instanceWrapper.getWrappedInstance();
//获取 class
Class<?> beanType = instanceWrapper.getWrappedClass();
if (beanType != NullBean.class) {
mbd.resolvedTargetType = beanType;
}
synchronized (mbd.postProcessingLock) {
if (!mbd.postProcessed) {
try {
//该方法会轮询 BeanPostProcessor 列表进行 bean 的增强操作
applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName);
}catch (Throwable ex) {
throw new BeanCreationException(mbd.getResourceDescription(), beanName,
"Post-processing of merged bean definition failed", ex);
}
mbd.postProcessed = true;
}
}
//是否是单例,是否允许循环引用,该单例 bean 是否在创建中
//isSingletonCurrentlyInCreation(beanName) 方法会去集合 singletonsCurrentlyInCreation 中搜寻 beanName
//如果存在,证明该 bean 正在被初始化,初始化完成之后会从该集合中删除掉,功能相当于锁
boolean earlySingletonExposure = (mbd.isSingleton() && this.allowCircularReferences &&
isSingletonCurrentlyInCreation(beanName));
if (earlySingletonExposure) {
if (logger.isTraceEnabled()) {
logger.trace("Eagerly caching bean '" + beanName +
"' to allow for resolving potential circular references");
}
//将 beanName 注册到 singletonFactories 和 registeredSingletons 中
addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean));
}
//添加一个 bean 的引用 exposedObject
Object exposedObject = bean;
try {
//该方法会根据配置来填充 mbd 中
populateBean(beanName, mbd, instanceWrapper);
//将信息填充到 exposedObject 中
exposedObject = initializeBean(beanName, exposedObject, mbd);
}catch (Throwable ex) {
if (ex instanceof BeanCreationException && beanName.equals(((BeanCreationException) ex).getBeanName())) {
throw (BeanCreationException) ex;
}else {
throw new BeanCreationException(
mbd.getResourceDescription(), beanName, "Initialization of bean failed", ex);
}
}
if (earlySingletonExposure) {
//getSingleton(...) 方法的第二个参数代表是否允许循环引用,这里输入的是 false(不允许)
//对于一般的 bean,这里获取到的 earlySingletonReference = null
Object earlySingletonReference = getSingleton(beanName, false);
if (earlySingletonReference != null) {
if (exposedObject == bean) {
exposedObject = earlySingletonReference;
}else if (!this.allowRawInjectionDespiteWrapping && hasDependentBean(beanName)) {
String[] dependentBeans = getDependentBeans(beanName);
Set<String> actualDependentBeans = new LinkedHashSet<>(dependentBeans.length);
for (String dependentBean : dependentBeans) {
if (!removeSingletonIfCreatedForTypeCheckOnly(dependentBean)) {
actualDependentBeans.add(dependentBean);
}
}
if (!actualDependentBeans.isEmpty()) {
throw new BeanCurrentlyInCreationException(beanName,
"Bean with name '" + beanName + "' has been injected into other beans [" +
StringUtils.collectionToCommaDelimitedString(actualDependentBeans) +
"] in its raw version as part of a circular reference, but has eventually been " +
"wrapped. This means that said other beans do not use the final version of the " +
"bean. This is often the result of over-eager type matching - consider using " +
"'getBeanNamesOfType' with the 'allowEagerInit' flag turned off, for example.");
}
}
}
}
//注册需要执行销毁方法的 bean
try {
registerDisposableBeanIfNecessary(beanName, bean, mbd);
}catch (BeanDefinitionValidationException ex) {
throw new BeanCreationException(
mbd.getResourceDescription(), beanName, "Invalid destruction signature", ex);
}
return exposedObject;
}
继续追踪 createBeanInstance(...) 方法:
//AbstractAutowireCapableBeanFactory.class
protected BeanWrapper createBeanInstance(String beanName, RootBeanDefinition mbd, @Nullable Object[] args) {
//获取到 bean 的 class
Class<?> beanClass = resolveBeanClass(mbd, beanName);
//如果 class 不为空,且修饰语非 public,且没有设置 accessible = true
if (beanClass != null && !Modifier.isPublic(beanClass.getModifiers()) && !mbd.isNonPublicAccessAllowed()) {
throw new BeanCreationException(mbd.getResourceDescription(), beanName,
"Bean class isn't public, and non-public access not allowed: " + beanClass.getName());
}
//如果 BeanDefinition 中有保存 Supplier,则使用该方式去获取 bean
//Supplier 是 jdk8 中配合函数式编程所添加的用于获取 bean 的接口
//Supplier 每次获取的 bean 都不是同一个
Supplier<?> instanceSupplier = mbd.getInstanceSupplier();
if (instanceSupplier != null) {
return obtainFromSupplier(instanceSupplier, beanName);
}
//如果有工厂方法,就用工厂方法进行实例化
if (mbd.getFactoryMethodName() != null) {
return instantiateUsingFactoryMethod(beanName, mbd, args);
}
boolean resolved = false;
boolean autowireNecessary = false;
if (args == null) {
synchronized (mbd.constructorArgumentLock) {
//查看是否缓存了构造器
if (mbd.resolvedConstructorOrFactoryMethod != null) {
resolved = true;
//这里要判断构造器的参数是否使用了 Autowire 注解
autowireNecessary = mbd.constructorArgumentsResolved;
}
}
}
if (resolved) {
if (autowireNecessary) {
//如果使用了 Autowire 注解就会进入这个方法进行实例化
return autowireConstructor(beanName, mbd, null, null);
}else {
//常规的实例化 bean
return instantiateBean(beanName, mbd);
}
}
//如果一个继承了 BeanPostProcessor 接口的 bean 的构造器参数使用了 Autowire 注解,会在此处单独处理
Constructor<?>[] ctors = determineConstructorsFromBeanPostProcessors(beanClass, beanName);
if (ctors != null || mbd.getResolvedAutowireMode() == AUTOWIRE_CONSTRUCTOR ||
mbd.hasConstructorArgumentValues() || !ObjectUtils.isEmpty(args)) {
return autowireConstructor(beanName, mbd, ctors, args);
}
//获取首选的构造器
//在该版本的 RootBeanDefinition 里,该方法没有方法体,直接返回 null
//也就是说,该代码是不启用的
ctors = mbd.getPreferredConstructors();
if (ctors != null) {
return autowireConstructor(beanName, mbd, ctors, null);
}
//实例化 bean
return instantiateBean(beanName, mbd);
}
继续追踪 instantiateBean(...) 方法:
//AbstractAutowireCapableBeanFactory.class
protected BeanWrapper instantiateBean(final String beanName, final RootBeanDefinition mbd) {
try {
Object beanInstance;
final BeanFactory parent = this;
//再次检测权限环境
//此例中没有涉及
if (System.getSecurityManager() != null) {
beanInstance = AccessController.doPrivileged((PrivilegedAction<Object>) () ->
getInstantiationStrategy().instantiate(mbd, beanName, parent),
getAccessControlContext());
}else {
//实例化 bean
beanInstance = getInstantiationStrategy().instantiate(mbd, beanName, parent);
}
//将 bean 包装成 BeanWrapper 并返回
BeanWrapper bw = new BeanWrapperImpl(beanInstance);
initBeanWrapper(bw);
return bw;
}catch (Throwable ex) {
throw new BeanCreationException(
mbd.getResourceDescription(), beanName, "Instantiation of bean failed", ex);
}
}
继续追踪 instantiate(...) 方法:
//SimpleInstantiationStrategy.class
public Object instantiate(RootBeanDefinition bd, @Nullable String beanName, BeanFactory owner) {
//不需要方法重载,就不需要 cglib 帮助了
if (!bd.hasMethodOverrides()) {
Constructor<?> constructorToUse;
synchronized (bd.constructorArgumentLock) {
//先尝试查看 BeanDefinition 中是否保存了构造器,如果没有保存,就在下方从 class 中拿出来
constructorToUse = (Constructor<?>) bd.resolvedConstructorOrFactoryMethod;
if (constructorToUse == null) {
final Class<?> clazz = bd.getBeanClass();
if (clazz.isInterface()) { //bean 不能是一个接口
throw new BeanInstantiationException(clazz, "Specified class is an interface");
}
try {
//这里验证权限设置
if (System.getSecurityManager() != null) {
constructorToUse = AccessController.doPrivileged(
(PrivilegedExceptionAction<Constructor<?>>) clazz::getDeclaredConstructor);
}else {
//获取构造器
constructorToUse = clazz.getDeclaredConstructor();
}
bd.resolvedConstructorOrFactoryMethod = constructorToUse;
}catch (Throwable ex) {
throw new BeanInstantiationException(clazz, "No default constructor found", ex);
}
}
}
//实例化 bean
return BeanUtils.instantiateClass(constructorToUse);
}else {
//使用 cglib 进行 bean 的实例化
return instantiateWithMethodInjection(bd, beanName, owner);
}
}
此小节是整个实例化 bean 过程中最冗长,也最核心的部分。
这中间 Spring 做了大量的验证和业务判断,但是实际上最终 bean 的实例化并不复杂。
4.15
finishRefresh();
追踪代码实现:
//AbstractApplicationContext.class
protected void finishRefresh() {
//清空缓存,即将 resourceCaches 这个 map 对象置空
clearResourceCaches();
//实例化一个类型为 DefaultLifecycleProcessor 的 bean,用于控制 bean 的生命周期
initLifecycleProcessor();
getLifecycleProcessor().onRefresh();
//刷新上下文事件
//ContextRefreshedEvent 并没有业务逻辑
publishEvent(new ContextRefreshedEvent(this));
//此方法会将 applicationContext 保存到 LiveBeansView 中的一个集合内
LiveBeansView.registerApplicationContext(this);
}
到此为止,正常的 ApplicationContext 的初始化流程就完成了。
4.16
看下方代码片段:
destroyBeans();
这个方法的实现:
//AbstractApplicationContext.class
protected void destroyBeans() {
getBeanFactory().destroySingletons();
}
destroySingletons() 是定义在 DefaultListableBeanFactory 中的方法:
//DefaultListableBeanFactory.class
public void destroySingletons() {
super.destroySingletons();
//manualSingletonNames 是一个用来存放已经被创建的单例 bean 的名字的 Set集合
this.manualSingletonNames.clear();
clearByTypeCache();
}
这里的 super.destroySingletons() 调用的是其父类 DefaultSingletonBeanRegistry 中的方法:
//DefaultSingletonBeanRegistry.class
public void destroySingletons() {
if (logger.isTraceEnabled()) {
logger.trace("Destroying singletons in " + this);
}
synchronized (this.singletonObjects) {
this.singletonsCurrentlyInDestruction = true;
}
String[] disposableBeanNames;
synchronized (this.disposableBeans) {
disposableBeanNames = StringUtils.toStringArray(this.disposableBeans.keySet());
}
for (int i = disposableBeanNames.length - 1; i >= 0; i--) {
destroySingleton(disposableBeanNames[i]);
}
this.containedBeanMap.clear();
this.dependentBeanMap.clear();
this.dependenciesForBeanMap.clear();
//清空相关的集合内的引用对象,并且销毁已经创建的 bean
clearSingletonCache();
}
再来看一下 clearByTypeCache() 方法:
//DefaultListableBeanFactory.class
private void clearByTypeCache() {
this.allBeanNamesByType.clear();
this.singletonBeanNamesByType.clear();
}
4.17
看下方代码片段:
cancelRefresh(ex);
这个方法的实现:
//AbstractApplicationContext.class
protected void cancelRefresh(BeansException ex) {
//传入的 exception 其实并没有用到
this.active.set(false);
}
active 是定义在 AbstractApplicationContext 中的一个 AtomicBoolean:
private final AtomicBoolean active = new AtomicBoolean();
这里将其的值设置为 false。
4.18
看下方代码片段:
resetCommonCaches();
具体实现
//AbstractApplicationContext.class
protected void resetCommonCaches() {
//主要是将 util 类里的一些 static 修饰的集合和 map 对象进行置空。
ReflectionUtils.clearCache();
AnnotationUtils.clearCache();
ResolvableType.clearCache();
CachedIntrospectionResults.clearClassLoader(getClassLoader());
}
从 4.16 到 4.18 的代码总体都比较简单,就是把各种的相关的集合、map、列表都清空掉,将 bean 的引用对象也都 remove 掉。
实际上是优雅关闭的过程。
二 一点唠叨
· Spring 的代码实在是太庞大了,刚开始想要尽可能详细的去解释每个组件,但是后来觉得难度略大
· Spring 的小部分组件和代码在笔者看来是有些莫名其妙的,且都没有查到详细而合理的解释
· Spring 的代码很明显使用了防御性的编程原则,保证了每个方法都足够健壮,但是同时造成了重复验证和冗余
· Spring 显然非常强调易用性和泛用性,提供了繁多的功能,甚至有部分是显得过于灵活的,如果笔者未读源码大概一辈子都不会知道
· Spring 对组件状态的控制异常复杂且精确
· Spring 对内存的控制很苛刻
· 仅为个人的学习笔记,可能存在错误或者表述不清的地方,有缘补充
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。